﻿using Blog.Core.AuthHelper;
using Blog.Core.AuthHelper.Policys;
using Blog.Core.Helpers;
using Blog.Core.IServices;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace Blog.Core.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class LoginController : Controller
    {
        ILogger<LoginController> _logger;
        readonly PermissionRequirement _requirement;
        private readonly IRoleModulePermissionServices _roleModulePermissionServices;

        public LoginController(ILogger<LoginController> logger, PermissionRequirement requirement, IRoleModulePermissionServices roleModulePermissionServices)
        {
            this._logger = logger;
            this._requirement = requirement;
            this._roleModulePermissionServices = roleModulePermissionServices;
        }

        [HttpPost]
        public IActionResult Post(string role)
        {
            string jwtStr = string.Empty;

            // 获取用户的角色名，请暂时忽略其内部是如何获取的，可以直接用 var userRole="Admin"; 来代替更好理解。
            var userRole = role;
            if (userRole != null)
            {
                // 将用户id和角色名，作为单独的自定义变量封装进 token 字符串中。
                TokenModelJwt tokenModel = new TokenModelJwt { Uid = 1, Role = userRole };
                jwtStr = JwtHelper.IssueJwt(tokenModel);//登录，获取到一定规则的 Token 令牌
            }
            else
            {
                jwtStr = "login fail!!!";
                this._logger.LogError(jwtStr);
            }

            return Ok(jwtStr);
        }

        [HttpPost]
        [ApiExplorerSettings(GroupName = "v2")]
        [Route("/api/v2/[controller]")]
        public async Task<IActionResult> PostV2(string name, string role)
        {
            string jwtStr = string.Empty;

            //如果是基于用户的授权策略，这里要添加用户;如果是基于角色的授权策略，这里要添加角色
            var claims = new List<Claim> {
                    new Claim(ClaimTypes.Name, name),
                    new Claim(JwtRegisteredClaimNames.Jti, "1"),
                    new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) };
            claims.AddRange(role.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));

            var data = await this._roleModulePermissionServices.GetRoleModuleAsync();
            var list = (from item in data
                        where item.IsDeleted == false
                        orderby item.Id
                        select new PermissionItem
                        {
                            Url = item.Module?.LinkUrl,
                            Role = item.Role?.Name,
                        }).ToList();

            _requirement.Permissions = list;
            var token = JwtHelper.IssueJwt(claims.ToArray(), _requirement);
            return Ok(token);
        }

        /// <summary>
        /// 获取JWT的方法4：给 JSONP 测试
        /// </summary>
        /// <param name="callBack"></param>
        /// <param name="id"></param>
        /// <param name="sub"></param>
        /// <param name="expiresSliding"></param>
        /// <param name="expiresAbsoulute"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("jsonp")]
        public void Getjsonp(string callBack, long id = 1, string sub = "Admin", int expiresSliding = 30, int expiresAbsoulute = 30)
        {
            TokenModelJwt tokenModel = new TokenModelJwt
            {
                Uid = id,
                Role = sub
            };

            string jwtStr = JwtHelper.IssueJwt(tokenModel);

            string response = string.Format("\"value\":\"{0}\"", jwtStr);
            string call = callBack + "({" + response + "})";
            Response.WriteAsync(call);
        }
    }
}
